package com.gc.web.controller.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Console;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gc.business.domain.*;
import com.gc.business.service.*;
import com.gc.common.constant.BusinessConstants;
import com.gc.common.constant.Constants;
import com.gc.common.utils.DateUtils;
import com.gc.common.utils.IdUtils;
import com.gc.common.utils.MoneyUtils;
import com.gc.common.utils.StringUtils;
import com.gc.framework.web.base.ApiBaseController;
import com.gc.system.domain.SysUser;
import com.gc.system.service.ISysUserService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 配件申请 控制层
 *
 * @author liujinteng
 * @date 2020-12-03
 */
@Slf4j
@Controller
@RequestMapping("/api/partApplication")
public class ApiPartApplicationController extends ApiBaseController {

    @Autowired
    private IPartApplicationService partApplicationService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IInventoryInfoService inventoryInfoService;

    @Autowired
    private IInventorySizeService inventorySizeService;

    @Autowired
    private IInventorySizePriceService inventorySizePriceService;

    @Autowired
    private IInventoryRecordService inventoryRecordService;

    @Autowired
    private IInventoryPriceService inventoryPriceService;

    @Autowired
    private ISysUserService sysUserService;


    /**
     * 库存列表
     */
    @GetMapping("/selectInventoryInfoList")
    @ResponseBody
    public Map<String, Object> selectInventoryInfoList(String token) {
        //该公司下的所有库存
        SysUser sysUser = sysUserService.selectUserById(getUserId(token));
        InventoryInfo inventoryInfo = new InventoryInfo();
        inventoryInfo.setAttrId(sysUser.getAttrId());
        return success(inventoryInfoService.list(inventoryInfo));
    }


    /**
     * 规格列表
     * <p>
     * 该库存物品有哪些规格
     *
     * @param inventoryId 库存ID
     */
    @GetMapping("/selectInventorySizeList")
    @ResponseBody
    public Map<String, Object> selectInventorySizeList(Long inventoryId) {
        if (inventoryId == null) {
            return error(Constants.UNVERIFY, "请选择配件");
        }
        LambdaQueryWrapper<InventoryPrice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InventoryPrice::getInventoryId, inventoryId);
        List<InventoryPrice> inventoryPriceList = inventoryPriceService.list(wrapper);
        if (inventoryPriceList == null || inventoryPriceList.size() == 0) {
            return error(Constants.UNVERIFY, "该配件暂无详细数据");
        }
        //中间表去除相同规格对象
        List<InventoryPrice> priceArrayList = inventoryPriceList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(InventoryPrice::getSizeId))), ArrayList::new));
        //返回中间表对应的规格数据
        ArrayList<InventorySize> inventorySizeList = new ArrayList<>();
        priceArrayList.forEach(inventoryPrice -> {
            InventorySize size = inventorySizeService.getById(inventoryPrice.getSizeId());
            inventorySizeList.add(size);
        });
        return success(inventorySizeList);
    }


    /**
     * 规格值列表
     * <p>
     * 该库存物品的具体规格有哪些规格值
     *
     * @param inventoryId 库存ID
     * @param sizeId      规格ID
     */
    @GetMapping("/selectInventorySizePriceList")
    @ResponseBody
    public Map<String, Object> selectInventorySizePriceList(Long inventoryId, Long sizeId) {
        if (inventoryId == null) {
            return error(Constants.UNVERIFY, "参数错误:请选择配件");
        }
        LambdaQueryWrapper<InventoryPrice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InventoryPrice::getInventoryId, inventoryId);
        wrapper.eq(InventoryPrice::getSizeId, sizeId);
        List<InventoryPrice> inventoryPriceList = inventoryPriceService.list(wrapper);
        if (inventoryPriceList == null || inventoryPriceList.size() == 0) {
            return error(Constants.UNVERIFY, "该配件暂无详细数据");
        }
        //返回中间表对应的规格值数据
        ArrayList<InventorySizePrice> inventorySizePriceList = new ArrayList<>();
        inventoryPriceList.forEach(inventoryPrice -> {
            InventorySizePrice sizePrice = inventorySizePriceService.getById(inventoryPrice.getPriceId());
            sizePrice.setSpecificationNum(inventoryPrice.getItemNum());
            inventorySizePriceList.add(sizePrice);
        });
        return success(inventorySizePriceList);
    }


    /**
     * 提交配件申请
     */
    @PostMapping("/savePartApplication")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> savePartApplication(String token, PartApplication partApplication) {
        SysUser user = userService.selectUserById(getUserId(token));
        if (partApplication.getInventoryId() == null) {
            return error(Constants.UNVERIFY, "请选择配件物品");
        }
        InventoryInfo inventoryInfo = inventoryInfoService.getById(partApplication.getInventoryId());
        if (inventoryInfo == null) {
            return error(Constants.UNVERIFY, "该配件不存在!!");
        }
        if (partApplication.getSizeId() == null || partApplication.getPriceId() == null) {
            return error(Constants.UNVERIFY, "请选择规格");
        }
        if (partApplication.getReceiveNum() == null) {
            return error(Constants.UNVERIFY, "请输入领取数量");
        }
        //查询库存中间表  查询该物品该规格下该规格值的数量
        LambdaQueryWrapper<InventoryPrice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InventoryPrice::getInventoryId, partApplication.getInventoryId());
        wrapper.eq(InventoryPrice::getSizeId, partApplication.getSizeId());
        wrapper.eq(InventoryPrice::getPriceId, partApplication.getPriceId());
        List<InventoryPrice> inventoryPriceList = inventoryPriceService.list(wrapper);
        if (CollUtil.isEmpty(inventoryPriceList)) {
            return error(Constants.UNVERIFY, "本配件暂无该规格数据");
        }
        //计算所有相同规格下配件的数量
        Integer sameSizeNum = 0;
        String sizeName = "";
        String priceName = "";
        for (InventoryPrice inventoryPrice : inventoryPriceList) {
            sameSizeNum = Integer.valueOf(MoneyUtils.moneyAdd(String.valueOf(inventoryPrice.getItemNum()), String.valueOf(sameSizeNum)));
            sizeName = inventoryPrice.getSizeName();
            priceName = inventoryPrice.getPriceName();
        }
        //查询待审核的出库记录
        PartApplication pa = new PartApplication();
        BeanUtils.copyProperties(partApplication,pa);
        pa.setAuditStatus("0");
        List<PartApplication> paList = partApplicationService.list(pa, null);
        //计算所有待审批的占用的配件数量
        Integer prepareNum = 0;
        for (PartApplication application : paList) {
            prepareNum = Integer.valueOf(MoneyUtils.moneyAdd(String.valueOf(application.getReceiveNum()), String.valueOf(prepareNum)));
        }
        //还可以领取数量
        Integer canReceiveNum = Integer.valueOf(MoneyUtils.moneySub(String.valueOf(sameSizeNum), String.valueOf(prepareNum)));
        Console.log("本配件该规格剩余数量:{},领取数量:{}", canReceiveNum, partApplication.getReceiveNum());
        //最后剩余数量
        Integer totalNum = Integer.valueOf(MoneyUtils.moneySub(String.valueOf(canReceiveNum), String.valueOf(partApplication.getReceiveNum())));
        if (totalNum < 0) {
            return error(Constants.UNVERIFY, "该规格的配件数量不足,剩余数量: " + canReceiveNum);
        }
        Console.log("剩余数量:{}", totalNum);
        //提交申请(待审核)
        partApplication.setPartName(inventoryInfo.getItemName());
        partApplication.setSizeName(sizeName);
        partApplication.setPriceName(priceName);
        partApplication.setPartTotal(sameSizeNum);//配件规格下数量
        partApplication.setUserId(user.getUserId());
        partApplication.setReceivePeople(user.getUserName());
        partApplication.setAuditStatus("0");
        partApplication.setCreateTime(DateUtil.date());
        partApplicationService.save(partApplication);
        //保存出库记录(待审核)
        InventoryRecord inventoryRecord = new InventoryRecord();
        inventoryRecord.setInventoryId(partApplication.getInventoryId());
        inventoryRecord.setSizeId(partApplication.getSizeId());
        inventoryRecord.setSizeName(partApplication.getSizeName());
        inventoryRecord.setPriceId(partApplication.getPriceId());
        inventoryRecord.setPriceName(partApplication.getPriceName());
        //inventoryRecord.setOrderNo("LB".concat(String.valueOf(IdUtils.getPrimaryKey())));
        inventoryRecord.setOrderNo(inventoryInfo.getOrderNo());
        inventoryRecord.setItemName(inventoryInfo.getItemName());
        inventoryRecord.setItemNum(String.valueOf(canReceiveNum));//配件规格下数量
        inventoryRecord.setRemainNum(String.valueOf(totalNum));//配件规格下剩余数量
        inventoryRecord.setReceiver(user.getUserName());
        inventoryRecord.setDrawTime(DateUtils.getDate());//yyyy-MM-dd
        inventoryRecord.setRecordType("2");//出库
        inventoryRecord.setAuditStatus("0");//待审核
        inventoryRecord.setProjectName(partApplication.getProjectName());//项目名称
        inventoryRecordService.save(inventoryRecord);
        //配件保存出库记录ID
        partApplication.setRecordId(inventoryRecord.getRecordId());
        partApplicationService.updateById(partApplication);
        return success(partApplication);
    }


    /**
     * 配件申请详情
     */
    @GetMapping("/selectPartApplicationInfo")
    @ResponseBody
    public Map<String, Object> selectPartApplicationInfo(Long partId) {
        if (partId == null) {
            return error(Constants.UNVERIFY, "参数错误:partId为空");
        }
        PartApplication partApplication = partApplicationService.getById(partId);
        if (partApplication == null) {
            return error(Constants.UNVERIFY, "未查找到相关数据");
        }
        SysUser user = userService.selectUserById(partApplication.getUserId());
        partApplication.setUser(user);
        InventorySize inventorySize = inventorySizeService.getById(partApplication.getSizeId());
        partApplication.setInventorySize(inventorySize);
        InventorySizePrice inventorySizePrice = inventorySizePriceService.getById(partApplication.getPriceId());
        partApplication.setInventorySizePrice(inventorySizePrice);
        return success(partApplication);
    }


    /**
     * 查询配件申请列表数量
     *
     * @param token
     * @return
     */
    @GetMapping("/queryApplicationListCount")
    @ResponseBody
    public Map<String, Object> queryApplicationListCount(String token) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        //我发起的 数量
        Map<String, Object> map1 = new HashMap<>();
        map1.put("title", "我发起的");
        List<PartApplication> partApplicationList = partApplicationService.selectPartApplicationList(getUserId(token), "0",null,null);
        map1.put("count", partApplicationList.size());
        mapList.add(map1);
        //待我审批 数量
        Map<String, Object> map2 = new HashMap<>();
        map2.put("title", "待我审批");
        List<PartApplication> waitApproveList = partApplicationService.selectPartApplicationList(getUserId(token), "1",null,null);
        map2.put("count", waitApproveList.size());
        mapList.add(map2);
        //我已审批 数量
        Map<String, Object> map3 = new HashMap<>();
        map3.put("title", "我已审批");
        List<PartApplication> doneApproveList = partApplicationService.selectPartApplicationList(getUserId(token), "2",null,null);
        map3.put("count", doneApproveList.size());
        mapList.add(map3);
        return success(mapList);
    }

    /**
     * 配件申请列表
     *
     * @param reviewType 0.我发起的 1.待我审批 2.审批完成
     */
    @GetMapping("/selectPartApplicationList")
    @ResponseBody
    public Map<String, Object> selectPartApplicationList(String token, String reviewType, Integer pageNum, Integer pageSize) {
        Long userId = getUserId(token);
        if (StringUtils.isEmpty(reviewType)){
            return error(Constants.UNVERIFY,"参数错误:reviewType为空");
        }
        List<PartApplication> partApplicationList = partApplicationService.selectPartApplicationList(userId, reviewType,pageNum,pageSize);
        Map<String, Object> map = new HashMap<>();
        map.put("pageNum",pageNum);
        map.put("list",partApplicationList);
        map.put("total",new PageInfo<>(partApplicationList).getTotal());
        return success(map);
    }


    /**
     * 审核配件申请
     *
     * @param auditStatus  审批状态(0:待审批;1:通过;2:驳回)
     */
    @PostMapping("/approvalPartApplication")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> approvalPartApplication(String token,String partId,String auditStatus,String rejectCause){
        //获取用户角色列表
        String userRoles = userService.selectUserRole(getUserId(token));
        //判断是否维保经理
        if (!userRoles.contains(BusinessConstants.KEEP_MANAGER)) {
            return error(Constants.UNVERIFY, "该用户不是维保经理");
        }
        PartApplication partApplication = partApplicationService.getById(partId);
        if (!partApplication.getAuditStatus().equals("0")){
            return error(Constants.UNVERIFY, "配件申请已审核");
        }
        //执行方法体
        String result = partApplicationService.executeMethod(partApplication,auditStatus,rejectCause);
        if (result.equals("1")){
            return error(Constants.UNVERIFY, "暂无该配件");
        }else if (result.equals("2")){
            return error(Constants.UNVERIFY, "本配件暂无该规格数据");
        }else if (result.equals("3")){
            return error(Constants.UNVERIFY,"配件数量不足");
        }
        partApplication.setAuditStatus(auditStatus);
        partApplication.setApproveId(getUserId(token));
        if (partApplicationService.updateById(partApplication)){
            InventoryRecord inventoryRecord = inventoryRecordService.getById(partApplication.getRecordId());
            SysUser user = userService.selectUserById(getUserId(token));
            inventoryRecord.setAuditor(user.getUserName());
            inventoryRecord.setAuditStatus(auditStatus);
            if (auditStatus.equals("2")){
                partApplication.setRejectCause(rejectCause);
            }
            inventoryRecordService.updateById(inventoryRecord);
            return success("审核完成");
        }
        return error(Constants.UNVERIFY,"审核失败");
    }
}
